﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;

using Microsoft.Win32;

using Google.GData.Spreadsheets;
using Google.GData.Client;
using Google.GData.Documents;

namespace WoodRobotics.PasswordKeeper.ModelView
{
    
    public class GoogleConnection : INotifyPropertyChanged
    {
        
        #region Constructor
        public GoogleConnection()
        {
        }
        #endregion
        
        #region Fields
        private SpreadsheetsService m_SSService;
        private SpreadsheetEntry m_SpreadSheet;
        private WorksheetEntry m_WorkSheet;
        
        private bool m_IsConnected = false;
        #endregion
        
        #region Properties
        public bool IsConnected
        {
            get { return m_IsConnected; }
            set
            {
                if (value == true)
                    throw new Exception("You can not manually set the connection state to true!");
                else
                {
                    m_IsConnected = false;
                    Disconnect();
                }
            }
        }
        public string FailedReasion { get; private set; }
        public string UserName
        {
            get 
            {
                if (Registry.CurrentUser.CreateSubKey(@"Software\WoodRobotics\PasswordKeeper").GetValueNames().Contains("EmailAddy"))
                    return Registry.CurrentUser.CreateSubKey(@"Software\WoodRobotics\PasswordKeeper").GetValue("EmailAddy").ToString();
                else
                    return "";
            }
            set 
            {
                Registry.CurrentUser.CreateSubKey(@"Software\WoodRobotics\PasswordKeeper").SetValue("EmailAddy", value, RegistryValueKind.String); 
            }
        }
        public string Password { get; set; }
        #endregion
        
        #region Methods
        public void Connect()
        {
            
            try
            {
                
                m_SSService = new SpreadsheetsService("WoodRobotics.PasswordKeeper");
                m_SSService.setUserCredentials(UserName, Password);
                
                m_SpreadSheet = GetPasswordList();
                
                if (m_SpreadSheet != null)
                {
                    m_WorkSheet = GetWorkSheet();
                    if (m_WorkSheet == null)
                        m_WorkSheet = CreateWorkSheet();
                }
                else
                {
                    m_SpreadSheet = CreateSpreadSheet();
                    m_WorkSheet = GetWorkSheet();
                }

                m_IsConnected = true;
                
            }
            catch (Exception WTF)
            {
                
                FailedReasion = WTF.Message;
                
                m_IsConnected = false;
                
                m_SSService = null;
                m_SpreadSheet = null;
                m_WorkSheet = null;
                
            }
            
        }
        public void Disconnect()
        {
            
            m_IsConnected = false;

            m_SSService = null;
            m_SpreadSheet = null;
            m_WorkSheet = null;
            
        }
        public ListEntry AddRow()
        {
            
            AtomLink l_FeedLink = m_WorkSheet.Links.FindService(GDataSpreadsheetsNameTable.ListRel, null);
            ListQuery l_Query = new ListQuery(l_FeedLink.HRef.ToString());
            ListFeed l_Feed = m_SSService.Query(l_Query);
            
            ListEntry l_NewRow = new ListEntry();

            ListEntry.Custom l_CurElement = new ListEntry.Custom();
            l_CurElement.LocalName = "source";
            l_CurElement.Value = "a";
            l_NewRow.Elements.Add(l_CurElement);

            l_CurElement = new ListEntry.Custom();
            l_CurElement.LocalName = "username";
            l_CurElement.Value = "b";
            l_NewRow.Elements.Add(l_CurElement);

            l_CurElement = new ListEntry.Custom();
            l_CurElement.LocalName = "password";
            l_CurElement.Value = "c";
            l_NewRow.Elements.Add(l_CurElement);

            ListEntry l_HoldEntry = l_Feed.Insert(l_NewRow);
            
            return l_HoldEntry;
            
        }
        public List<ListEntry> GetPasswords()
        {
            
            List<ListEntry> l_Entrys = new List<ListEntry>();

            AtomLink l_FeedLink = m_WorkSheet.Links.FindService(GDataSpreadsheetsNameTable.ListRel, null);
            ListQuery l_Query = new ListQuery(l_FeedLink.HRef.ToString());
            ListFeed l_Feed = m_SSService.Query(l_Query);


            foreach (ListEntry l_Entry in l_Feed.Entries)
                l_Entrys.Add(l_Entry);

            return l_Entrys;
            
        }
        
        private SpreadsheetEntry GetPasswordList()
        {
            
            SpreadsheetEntry l_ReturnSheet = null;
            Google.GData.Spreadsheets.SpreadsheetQuery l_QuerySheets = new Google.GData.Spreadsheets.SpreadsheetQuery();
            SpreadsheetFeed l_Feed = m_SSService.Query(l_QuerySheets);
            
            foreach (SpreadsheetEntry l_Sheet in l_Feed.Entries)
            {
                if (l_Sheet.Title.Text == "WoodRoboticsPasswords")
                {
                    l_ReturnSheet = l_Sheet;
                    break;
                }
            }
            
            return l_ReturnSheet;
            
        }
        private WorksheetEntry GetWorkSheet()
        {
            
            WorksheetEntry l_ReturnSheet = null;
            
            AtomLink link = m_SpreadSheet.Links.FindService(GDataSpreadsheetsNameTable.WorksheetRel, null);
            
            WorksheetQuery l_Query = new WorksheetQuery(link.HRef.ToString());
            WorksheetFeed l_Feed = m_SSService.Query(l_Query);
            
            foreach (WorksheetEntry l_WorkSheet in l_Feed.Entries)
            {
                if (l_WorkSheet.Title.Text == "WoodRoboticsPasswords")
                {
                    l_ReturnSheet = l_WorkSheet;
                    break;
                }
            }
            
            return l_ReturnSheet;
            
        }
        private SpreadsheetEntry CreateSpreadSheet()
        {
            
            DocumentsService l_DS = new DocumentsService("WoodRobticsPasswords");
            l_DS.setUserCredentials(UserName, Password);
            l_DS.UploadDocument(GetDefaultXLS(), "WoodRoboticsPasswords");
            l_DS = null;
            
            return GetPasswordList();
            
        }
        private WorksheetEntry CreateWorkSheet()
        {
            throw new Exception("Well I could have implemented this ... but I'm lazy!! ;')~");
        }
        private string GetDefaultXLS()
        {

            string l_DefaultXLS = Environment.GetEnvironmentVariable("Temp") + "\\WoodRoboticsPasswords.xls";
            System.IO.FileStream l_XLSFileStream = null;
            
            if (System.IO.File.Exists(l_DefaultXLS))
                l_XLSFileStream = new System.IO.FileStream(l_DefaultXLS, System.IO.FileMode.Truncate, System.IO.FileAccess.Write, System.IO.FileShare.ReadWrite);
            else
                l_XLSFileStream = new System.IO.FileStream(l_DefaultXLS, System.IO.FileMode.Create, System.IO.FileAccess.Write, System.IO.FileShare.ReadWrite);

            
            System.IO.Stream l_Resource = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("WoodRobotics.PasswordKeeper.DefaultXLS.WoodRoboticsPasswords.xls");
            byte[] l_XLSBuff = new byte[l_Resource.Length];
            l_Resource.Read(l_XLSBuff, 0, l_XLSBuff.Length);
            l_Resource.Close();

            l_XLSFileStream.Write(l_XLSBuff, 0, l_XLSBuff.Length);
            l_XLSFileStream.Close();
            
            return l_DefaultXLS;
            
        }
        
        private void NotifyPropertChanged(string PropertyName)
        {
            
        }
        #endregion
        
        #region INotifyPropertyChanged Members
        public event PropertyChangedEventHandler PropertyChanged;
        #endregion
        
    }
    
}
